;(function(window, document) {
    // props
    var defaultSettings = {
        tableExcel:'tableExcel',
        tableSele:'tableSele',
        tableEventCont:'tableEventCont',
    };
  
    function tableExcel(options) {
        var _this = this;
         _this = Object.assign(_this, defaultSettings, options || {});

        _this.init = function() {
            setTimeout(function(){
                _this._init();
            },0);
        };

        setTimeout(function(){
            _this._init();
        },0);

    }
    
    tableExcel.prototype = {
        _init: function() {
            this.tabAll = document.querySelectorAll('.' + this.tableExcel);
            this.tabRightEvent = document.querySelector('.'+this.tableEventCont);
            this.selectCell = [];
            this.recordTr = {
                max:-1,
                min:-1,
            };
            this.oldRecordTr = {
                max:-1,
                min:-1,
            };
            this.recordTd = {
                max:-1,
                min:-1,
            };
            this.oldRecordTd = {
                max:-1,
                min:-1,
            };
            this.endTr={
                max:-1,
                min:-1,
            };
            this.endTd={
                max:-1,
                min:-1,
            };
            this._tdInit(this._tdOptDown);
            this._tabRightEven();
            var _this = this;
            document.body.onmouseup = function(event){
                event = event || window.event;
                _this._tabRightContToggle(false);
                
                _this._tdInit(function(objs){
                    if(event.button === 0 || event.button === '0'){
                        objs.classList.remove(_this.tableSele);
                    }
                    objs.onmousemove = null;
                    objs.onmouseup = null;
                    return false;
                });
            };
        },
        // 求差
        _mathReduce:function(arr){
            var max = arr[0];
            var min = arr[0];
            for(var i=1;i<arr.length;i++){
                max = arr[i] > max ? arr[i] : max;
                min = arr[i] < min ? arr[i] : min;
            }
            return (max - min + 1);
        },
        // 合并
        _cellMerge:function(){
            var _this = this;
            var row = _this._mathReduce([_this.recordTr.max,_this.recordTr.min,_this.endTr.max,_this.endTr.min]);
            var col = _this._mathReduce([_this.recordTd.max,_this.recordTd.min,_this.endTd.max,_this.endTd.min]);
            for(var j = 0;j<_this.selectCell.length;j++){
                if(j === 0){
                    _this.selectCell[j].rowSpan = row;
                    _this.selectCell[j].colSpan = col;
                }else{
                    if(_this.selectCell[j].children.length > 0){
                        for(var i = 0; i < _this.selectCell[j].children.length ; i++){
                            _this.selectCell[0].appendChild(_this.selectCell[j].children[i]);
                        }
                    }
                    _this.selectCell[j].parentNode.removeChild(_this.selectCell[j]);
                }
            }
        },
        // 拆分
        _cellSplit:function(objs){
            var row = objs.rowSpan;
            var col = objs.colSpan;
            var tdval = objs.tdval;
            var trval = objs.trval;
            objs.rowSpan = 1;
            objs.colSpan = 1;
            var first = 0;
            var trLen = objs.parentNode.parentNode.parentNode.children[0].children;
            function rowTest (tdLen,trItem,tdvalMin){
                var isTrAppend = true;
                for(j = 0; j<tdLen.length;j++){
                    if(tdLen[j].tdval && tdvalMin  === tdLen[j].tdval.min){
                        for(var b=0;b<col;b++){
                            isTrAppend  = false;
                            if(first !== 0 ){
                                var newObj = objs.cloneNode(false);
                                insertAfter(newObj,tdLen[j]);
                            }
                            first++;
                        }
                    }
                }
                if(isTrAppend){
                    if(tdvalMin - 1 > -1){
                        rowTest(tdLen ,trItem,(tdvalMin - 1));
                    }else{
                        for(var k=0;k<col;k++){
                            isTrAppend  = false;
                            if(first !== 0 ){
                                var _newObj = objs.cloneNode(false);
                                trItem.insertBefore(_newObj,trItem.children[0]);
                            }
                            first++;
                        }
                    }
                }
            }

            for(var i = 0; i<trLen.length;i++){
                if(trval.max >= i && i >= trval.min){
                    var tdLen = trLen[i].children;
                    if(tdLen.length > 0){
                        rowTest (tdLen ,trLen[i],(tdval.min - 1));
                    }else{
                        for(var d=0;d<col;d++){
                            if(first !== 0 ){
                                var newObj = objs.cloneNode(false);
                                trLen[i].appendChild(newObj);
                            }
                            first++;
                        }
                    }
                }
            }

            if(!!this.extend.cellSplit){
                this.extend.cellSplit(objs);
            }
        },

        // 前插入行
        _firstInsRow: function(objs){
            var newObj = objs.parentNode.cloneNode(false);
            var trLastMax = objs.parentNode.trLastMax;
            var trvalMin = objs.trval.min;
            var beforeVal = 0;
            this._tdLogic(objs.parentNode.parentNode.parentNode,function(obj,_tdval,_trval,_item,_this){
                if(_trval.max >= trvalMin && _trval.min < trvalMin){
                    obj.rowSpan = obj.rowSpan + 1;
                    beforeVal = beforeVal +  obj.colSpan;
                }
            });
            for(var i = 0; i<trLastMax-beforeVal;i++){
                var cellCopy = objs.cloneNode(false);
                cellCopy.colSpan = 1;
                cellCopy.rowSpan = 1;
                newObj.appendChild(cellCopy);
            }
            objs.parentNode.parentNode.insertBefore(newObj,objs.parentNode);
            if(!!this.extend.firstInsRow){
                this.extend.firstInsRow();
            }
        },
        // 后插入行
        _afterInsRow: function(objs){
            var trLen = objs.parentNode.parentNode.parentNode.children[0].children;
            var newObj = objs.parentNode.cloneNode(false);
            var trLastMax = objs.parentNode.trLastMax;
            var trvalMax = objs.trval.max;

            var afterVal = 0;
            this._tdLogic(objs.parentNode.parentNode.parentNode,function(obj,_tdval,_trval,_item,_this){
                if(_trval.max > trvalMax && _trval.min <= trvalMax){
                    obj.rowSpan = obj.rowSpan + 1;
                    afterVal = afterVal +  obj.colSpan;
                }
            });

            for(var i = 0; i<trLastMax-afterVal;i++){
                var cellCopy = objs.cloneNode(false);
                cellCopy.colSpan = 1;
                cellCopy.rowSpan = 1;
                newObj.appendChild(cellCopy);
            }
            insertAfter(newObj,trLen[objs.trval.max]);
            
            if(!!this.extend.firstInsRow){
                this.extend.firstInsRow();
            }
            
        },

        // 删除行
        _deleteRow:function(objs){
            var trvalMin = objs.trval.min;
            this._tdLogic(objs.parentNode.parentNode.parentNode,function(obj,_tdval,_trval,_item,_this){
                if(_trval.max >= trvalMin && _trval.min < trvalMin){
                    obj.rowSpan = obj.rowSpan - 1;
                }
            });
            var trChild = objs.parentNode.children;


            this._cellSplit(objs);
            this._init();

     
            for(var i = 0; i<trChild.length;i++){
                var item =  trChild[i];
                if(item.trval.isTrOr){
                    var child = objs.parentNode.parentNode.children[trvalMin+1].children;
                    trTest(item,child,item.tdval.min - 1);
                }
            }

            function trTest (item,child,tdvalMin){
                var isTrAppend = true;
                for(var j = 0; j < child.length;j++){
                    if(child[j].tdval && child[j].tdval.min === tdvalMin ){
                        item.rowSpan = item.rowSpan - 1;
                        insertAfter(item,child[j]);
                        isTrAppend = false;
                        i--;
                    }
                }
                if(isTrAppend){
                    if(tdvalMin - 1 > -1){
                        trTest(item,child,tdvalMin - 1);
                    }else{
                        item.rowSpan = item.rowSpan - 1;
                        child[0].parentNode.insertBefore(item,child[0]);
                        isTrAppend  = false;
                        i--;
                    }
                }
            }
            

            objs.parentNode.parentNode.removeChild(objs.parentNode);


        },
        // 前插入列
        _firstInsCol:function(objs){
            var tdvalMin = objs.tdval.min;
            
            var trList = objs.parentNode.parentNode.children;
            for(var i = 0;i<trList.length;i++){
                var tdList = trList[i].children;
                
                function tdTest(tdMax){
                    var isTdAppend = true;
                    for(var j = 0;j<tdList.length;j++){
                        if(tdList[j].tdval && tdList[j].tdval.max === tdMax){
                            isTdAppend = false;
                            var cellCopy = objs.cloneNode(false);
                            cellCopy.colSpan = 1;
                            cellCopy.rowSpan = 1;
                            insertAfter(cellCopy,tdList[j]);
                            j++;
                        }else if(tdList[j].tdval.isTdOr && tdList[j].tdval.min < tdvalMin && tdList[j].tdval.max >= tdvalMin){
                            isTdAppend = false;
                            tdList[j].colSpan = tdList[j].colSpan + 1;
                            i = tdList[j].trval.max ;
                        }

                    }
                    if(isTdAppend){
                        if(tdMax-1 > -1){
                            tdTest(tdMax-1);
                        }else{
                            var _cellCopy = objs.cloneNode(false);
                            _cellCopy.colSpan = 1;
                            _cellCopy.rowSpan = 1;
                            tdList[0].parentNode.insertBefore(_cellCopy,tdList[0]);
                            isTdAppend = false;
                        }
                    }
                            
                }

                tdTest(tdvalMin -1);
            }
        },

        // 后插入列
        _afterInsCol: function(objs){
            var tdvalMax = objs.tdval.max;
            
            var trList = objs.parentNode.parentNode.children;

            for(var i = 0;i<trList.length;i++){
                var tdList = trList[i].children;
                function tdTest(tdMax){
                    var isTdAppend = true;
                    for(var j = 0;j<tdList.length;j++){
                        if(tdList[j].tdval && tdList[j].tdval.max === tdMax){
                            isTdAppend = false;
                            var cellCopy = objs.cloneNode(false);
                            cellCopy.colSpan = 1;
                            cellCopy.rowSpan = 1;
                            insertAfter(cellCopy,tdList[j]);
                            j++;
                        }else if(tdList[j].tdval.isTdOr && tdList[j].tdval.min <= tdvalMax && tdList[j].tdval.max > tdvalMax){
                            isTdAppend = false;
                            tdList[j].colSpan = tdList[j].colSpan + 1;
                            i = tdList[j].trval.max ;
                        }

                    }
                    if(isTdAppend){
                        if(tdMax-1 > -1){
                            tdTest(tdMax-1);
                        }else{
                            var _cellCopy = objs.cloneNode(false);
                            _cellCopy.colSpan = 1;
                            _cellCopy.rowSpan = 1;
                            tdList[0].parentNode.insertBefore(_cellCopy,tdList[0]);
                            isTdAppend = false;
                        }
                    }
                            
                }

                tdTest(tdvalMax);
            }
        },

        // 删除列
        _deleteCol: function(objs){


            var tdvalMin = objs.tdval.min;
            
            var trList = objs.parentNode.parentNode.children;

            this._cellSplit(objs);
            this._init();

            for(var i = 0;i<trList.length;i++){
                var tdList = trList[i].children;
                for(var j = 0;j<tdList.length;j++){
                    if(tdList[j].tdval && tdList[j].tdval.min === tdvalMin){
                        if(tdList[j].tdval.isTdOr){
                            tdList[j].colSpan = tdList[j].colSpan - 1;
                        }else{
                            tdList[j].parentNode.removeChild(tdList[j]);
                        }
                    }else if(tdList[j].tdval.isTdOr &&  tdList[j].tdval.max >= tdvalMin && tdList[j].tdval.min < tdvalMin){
                        tdList[j].colSpan = tdList[j].colSpan - 1;
                    }

                }
            }
        },
        // 右击事件
        _rightEvent:function(objs){
            var _this = this;
            var list = this.tabRightEvent.querySelectorAll('a');

            for(var i=0;i<list.length;i++){
                list[i].onclick = function(){
                    var name = this.className;
                    // console.log(name);
                    switch (name){
                        // 合并
                        case 'cellMerge' :
                            _this._cellMerge();
                        break;

                        //拆分
                        case 'cellSplit' :
                            _this._cellSplit(objs);
                            
                        break;
                        
                        // 前插入行
                        case 'firstInsRow' :
                            _this._firstInsRow(objs);
                        break;

                        // 后插入行
                        case 'afterInsRow' :
                            _this._afterInsRow(objs);
                        break;


                        // 删除当前行
                        case 'deleteRow' :
                            _this._deleteRow(objs);
                        break;


                        // 前插入列
                        case 'firstInsCol' :
                            _this._firstInsCol(objs);
                        break;

                        // 后插入列
                        case 'afterInsCol' :
                            _this._afterInsCol(objs);
                        break;


                        // 删除当前列
                        case 'deleteCol' :
                            _this._deleteCol(objs);
                        break;


                        // 表格属性
                        // 行属性
                        // 单元格属性
                        case name :
                            if(!!_this.extend[name]){
                                _this.extend[name](objs);
                            }
                        break;

                    }
                        _this._init();
                    
                };
            }

        },

        // 右击控制
        _tabRightEven:function(){
            var _this = this;
            this._tdInit(function(objs,tdval,trval){
                objs.oncontextmenu = function(e){
                    e.preventDefault();
                    _this.selectCell = document.querySelectorAll('.'+_this.tableSele);
                    _this._tabRightContToggle(true,e);
                    _this._rightEvent(objs,tdval,trval);
                    return false;
                };
            });
        },
        // 右击控制样式
        _tabRightContToggle:function(bool,event){
            var obj = this.tabRightEvent.style;
            var YT = 0;
            if(bool){
                if(document.body.clientHeight - 272 < event.clientY){
                    YT = document.body.clientHeight - 275 - event.clientY;
                }
            }
            obj.left = ( bool ? event.clientX : 0 )+ 'px';
            obj.top = ( bool ? (event.clientY + YT): 0 )+ 'px';

            obj.display = bool ? 'block':'none';
        },

        // 多table遍历
        _tdInit:function(callback){
            for(var i=0;i<this.tabAll.length;i++){
                this._tdLogic(this.tabAll[i],callback);
            }
        },

        // td遍历逻辑 添加真实坐标
        _tdLogic:function(item,callback){
            var trLen = item.children[0].children;
            var row = [];

            for(var j = 0;j<trLen.length;j++){
                var tdLen = trLen[j].children;
                var kmax = -1;
                if(tdLen.length === 0){
                    for(var n = 0; n<row.length;n++){
                        if(!!row[n]){
                            row[n] --;
                        }
                    }
                }
                for(var k = 0; k < tdLen.length; k ++){
                    
                    kmax++;
                    var isTdOr = false;
                    var isTrOr = false;

                    function _trMap (){
                        if(!!row[kmax]){
                            row[kmax] --;
                            kmax++;
                            _trMap();
                        }
                    };
                    _trMap();


                    var kmin = kmax;

               
                    if(tdLen[k].colSpan > 1){
                        kmax = kmax + tdLen[k].colSpan-1;
                        isTdOr = true;
                    }
                    
                    if(tdLen[k].rowSpan > 1){
                        row[kmin] = tdLen[k].rowSpan-1;
                        if(tdLen[k].colSpan > 1){
                            for(var m = 1; m<tdLen[k].colSpan; m++){
                                row[kmin+m] = tdLen[k].rowSpan -1 ;
                            }
                        }
                        isTrOr = true;
                    }

                    var tdval = {
                        min:kmin,
                        max:kmax,
                        isTdOr:isTdOr,
                    };

                    var trval = {
                        min:j,
                        max:(j + tdLen[k].rowSpan - 1),
                        isTrOr:isTrOr,
                    };

                    tdLen[k].tdval = tdval;
                    tdLen[k].trval = trval;
                    callback(tdLen[k],tdval,trval,item,this);
                }

                
                trLen[j].trLastMax = kmax + 1;
                if(kmax <= row.length){
                    for(var s = kmax; s<row.length;s++){
                        if(!!row[s]){
                            row[s] --;
                        }
                    }
                }
                
            }
        },

        // 选区操作按下
        _tdOptDown: function(obj,tdval,trval,item,_this){
            obj.ondragstart = function(){
                return false;
            };
            obj.onmousedown = function(event){
                event = event || window.event;
                if(event.stopPropagation){
                    event.stopPropagation();
                }else{
                    event.cancelBubble = true;
                }
                _this._tabRightContToggle(false);

                if(event.button === 0 || event.button === '0'){
                    _this.recordTr = trval;
                    _this.oldRecordTr = trval;
                    _this.recordTd = tdval;
                    _this.oldRecordTd = tdval;
                    _this._tdInit(function(objs){
                        objs.classList.remove(_this.tableSele);
                    });
                    _this._tdLogic(item,_this._tdOptMove);
                    _this._tdLogic(item,_this._tdOptUp);
                }
            };
        },

        // 选区移动判断填充处理
        _tdOptFn:function(tdval,trval,item,_this){
            var tdMax =( tdval.isTdOr && _this.recordTd.min > tdval.max) ? tdval.min : tdval.max;
            var oldTdMax = (_this.recordTd.isTdOr && _this.recordTd.min < tdMax) ?  _this.recordTd.min : _this.recordTd.max;
            
       
            var trMax = ( trval.isTrOr && _this.recordTr.min > trval.max) ? trval.min : trval.max;
            var oldTrMax = ( _this.recordTr.isTrOr && _this.recordTr.min < trMax) ?  _this.recordTr.min : _this.recordTr.max;
            _this._tdLogic(item,function(objs,tdInd,trInd){
                var tdNewMax = tdInd.max;
                var tdNewMin = tdInd.min;
                var trNewMax = trInd.max;
                var trNewMin = trInd.min;

                if(
                    (
                        (
                            
                            trNewMax >= trMax && trNewMin <= trMax  || 
                            trNewMax >= oldTrMax && trNewMin <= oldTrMax  || 
                        
                            (
                                ( oldTrMax >= trMax && trNewMax <=  oldTrMax && trNewMax >= trMax) ||
                                ( oldTrMax <= trMax && trNewMax >=  oldTrMax && trNewMax <= trMax) 
                            )
                            
                        ) &&
                        (
                            (
                                tdInd.isTdOr &&
                                (
                                    (
                                        ( oldTdMax >= tdMax && tdNewMax <=  oldTdMax && tdNewMax >= tdMax) ||
                                        ( oldTdMax <= tdMax && tdNewMax >=  oldTdMax && tdNewMax <= tdMax)
                                    ) ||
                                    (
                                        ( oldTdMax >= tdMax && tdNewMin <=  oldTdMax && tdNewMin >= tdMax) ||
                                        ( oldTdMax <= tdMax && tdNewMin >=  oldTdMax && tdNewMin <= tdMax)
                                    )
                                )
                            ) ||
                            (
                                ( oldTdMax >= tdMax && tdNewMax <=  oldTdMax && tdNewMax >= tdMax) ||
                                ( oldTdMax <= tdMax && tdNewMax >=  oldTdMax && tdNewMax <= tdMax) 
                            )
                        )
                    )
                ){
                    objs.classList.add(_this.tableSele);
                } else {
                    objs.classList.remove(_this.tableSele);   
                }
            });
        },


        // 补位处理
        _tdSelectRegion: function(tdval,trval,item,_this){
            var tdvalNew = tdval;
            var trvalNew = trval;
            var isTdMinBool = false;
            var isTdMaxBool = false;
            var isTrMinBool = false;
            var isTrMaxBool = false;

            _this._tdLogic(item,function(objs,_tdval,_trval,_item,__this){
                if(objs.className.indexOf(_this.tableSele) > -1){
                    if(_tdval.isTdOr){
                        if(tdval.max >= _this.recordTd.min){
                            if(_this.recordTd.min >= _tdval.min){
                                isTdMinBool = true;
                                _this.recordTd = _tdval;
                            }
                            if(tdvalNew.max < _tdval.max){
                                isTdMaxBool = true;
                                tdvalNew = _tdval;
                            }
                        }else{
                            if(_this.recordTd.max <= _tdval.max){
                                isTdMinBool = true;
                                _this.recordTd = _tdval;
                            }

                            if(tdvalNew.min > _tdval.min){
                                isTdMaxBool = true;
                                tdvalNew = _tdval;
                            }
                        }
                    }

                    if(_trval.isTrOr){
                        if(_this.recordTr.min <=  trval.max){
                            
                            if(_this.recordTr.min >= _trval.min){
                                isTrMinBool = true;
                                _this.recordTr = _trval;
                            }
                            
                            if(trvalNew.max <= _trval.max){
                                isTrMaxBool = true;
                                trvalNew = _trval;
                            }


                        }else{

                            if(_this.recordTr.max <= _trval.max){
                                isTrMinBool = true;
                                _this.recordTr = _trval;
                            }

                            if(trvalNew.min >= _trval.min){
                                isTrMaxBool = true;
                                trvalNew = _trval;
                            }
                        }
                    }
                }
            });
            if(!isTdMaxBool){
                tdvalNew = tdval;
            }
            if(!isTdMinBool){
                _this.recordTd = _this.oldRecordTd;
            }
            if(!isTrMaxBool){
                trvalNew = trval;
            }
            if(!isTrMinBool){
                _this.recordTr = _this.oldRecordTr;
            }
            _this.endTr = trvalNew;
            _this.endTd = tdvalNew;
            setTimeout(function(){
                _this._tdOptFn(tdvalNew,trvalNew,item,_this);
            },0);
        },


        // 选区移动处理
        _tdOptMove:function(obj,tdval,trval,item,_this){
            obj.onmousemove = function(e){
                e = e || window.event;
                if(e.stopPropagation){
                    e.stopPropagation();
                }else{
                    e.cancelBubble = true;
                }
                _this._tdSelectRegion(tdval,trval,item,_this);
            };
        },
        // 选区操作结束
        _tdOptUp:function(obj,tdval,trval,item,_this){
            obj.onmouseup = function(e){
                // e = e || window.event;
                // if(e.stopPropagation){
                //     e.stopPropagation();
                // }else{
                //     e.cancelBubble = true;
                // }
                
                _this._tdLogic(item,function(objs){
                    objs.onmousemove = null;
                    objs.onmouseup = null;
                    return false;
                });
                _this._tdSelectRegion(tdval,trval,item,_this);
                // return false;
            };
        }
    };
    window.tableExcel = tableExcel;
  })(window, document);

  layui.define([], function(exports){
    exports('tableExcel', tableExcel);
  });
  